package org.zn.mvcbase.rest;

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.zn.mvcbase.rest.spi.RestStatusHandlerChain;

import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;

public class RestEntityFactroy {

	private RestTemplate restTemplate;
	
	private ObjectMapper objectMapper;
	
	private HttpHeaders baseheader;
	
	private SessionBinding sessionBinding;
	
	private List<RestStatusHandlerChain> restStatusHandler;


	public RestEntityFactroy(RestTemplate restTemplate, ObjectMapper objectMapper) {
		super();
		this.restTemplate = restTemplate;
		this.objectMapper = objectMapper;
		this.objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 
	}
	
	public  void setBaseheader(Map<? extends String, ? extends List<String>> headersmap){
		
		baseheader=new HttpHeaders();
		
		baseheader.putAll(headersmap);

	}
	

	public List<RestStatusHandlerChain> getRestStatusHandler() {
		return restStatusHandler;
	}

	public void setRestStatusHandler(List<RestStatusHandlerChain> restStatusHandler) {
		this.restStatusHandler = restStatusHandler;
	}

	public SessionBinding getSessionBinding() {
		return sessionBinding;
	}

	public void setSessionBinding(SessionBinding sessionBinding) {
		this.sessionBinding = sessionBinding;
	}

	public RestEntity getRestEntity(HttpHeaders headers) {
	
		RestEntity restEntity=new RestEntity();
		
		 HttpEntity<?> httpEntity=new HttpEntity<>(headers);
		restEntity.setObjectMapper(objectMapper);
		restEntity.setRestTemplate(restTemplate);
		restEntity.setRequestEntity(httpEntity);

		return restEntity;

	}
	
	
	public RestEntity getRestEntity() {
		
		RestEntity restEntity=new RestEntity();
		
		 HttpEntity<?> httpEntity=new HttpEntity<>(baseheader);
		restEntity.setObjectMapper(objectMapper);
		restEntity.setRestTemplate(restTemplate);
		restEntity.setRequestEntity(httpEntity);

		return restEntity;

	}
	

	public RestEntity getRestEntity(HttpMethod method,String url) {
		
		RestEntity restEntity=new RestEntity();
		
		HttpEntity<?> httpEntity=new HttpEntity<>(baseheader);
		
		restEntity.setObjectMapper(objectMapper);
		restEntity.setRestTemplate(restTemplate);
		restEntity.setRequestEntity(httpEntity);
		restEntity.setMethod(method);
		restEntity.setUrl(url);
		return restEntity;
	}


	
	public RestEntity getRestEntity(HttpMethod method,String url,HttpSession session) {
		
	RestEntity restEntity=new RestEntity();
		
		HttpEntity<?> httpEntity=new HttpEntity<>(sessionBinding.bind(session, baseheader));
		
		restEntity.setObjectMapper(objectMapper);
		restEntity.setRestTemplate(restTemplate);
		restEntity.setRequestEntity(httpEntity);
		restEntity.setMethod(method);
		restEntity.setUrl(url);


		return restEntity;

	}


	/**
	 * 单一上传
	 * @param file
	 * @param params
	 * @return
	 */
	@Deprecated
	public RestEntity getRestEntity(String url , String upload, File file, Map<String,Object> params,HttpSession session){
		//文件源
		FileSystemResource resource = new FileSystemResource(file);
		MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
		if(params != null && params.size() > 0){
			params.forEach( (k,v) -> body.add(k,v) );
		}
		body.add(upload,resource);

		RestEntity restEntity=new RestEntity();
		
		

		
		HttpEntity<MultiValueMap> httpEntity =new HttpEntity<MultiValueMap>(body,baseheader);
		restEntity.setRequestEntity(httpEntity);
		restEntity.setUrl(url);

		restEntity.setObjectMapper(objectMapper);
		restEntity.setRestTemplate(restTemplate);
		restEntity.setMethod(HttpMethod.POST);

		return restEntity;

	}



	public RestEntity getRestEntity(String url , final  String upload, MultipartFile file, Map<String,Object> params,HttpSession session) throws IOException {
		//文件源
		/*FileSystemResource resource = new FileSystemResource(file);*/

		ByteArrayResource resource = new ByteArrayResource(file.getBytes()){
			@Override
			public String getFilename() throws IllegalStateException {
				return file.getOriginalFilename();
			}
		};


		MultiValueMap<String, Object> body = new LinkedMultiValueMap<>();
		if(params != null && params.size() > 0){
			params.forEach( (k,v) -> body.add(k,v) );
		}
		body.add(upload,resource);

		RestEntity restEntity=new RestEntity();
		
		
	//	HttpEntity<MultiValueMap> httpEntity =new HttpEntity<MultiValueMap>(body,baseheader);
		
		HttpEntity<MultiValueMap> httpEntity=new HttpEntity<>(body,sessionBinding.bind(session, baseheader));

		restEntity.setRequestEntity(httpEntity);
		
		restEntity.setUrl(url);

		restEntity.setObjectMapper(objectMapper);
		restEntity.setRestTemplate(restTemplate);
		restEntity.setMethod(HttpMethod.POST);

		return restEntity;

	}




	/**
	 * Getter for property 'restTemplate'.
	 *
	 * @return Value for property 'restTemplate'.
	 */
	public RestTemplate getRestTemplate() {
		return restTemplate;
	}

	/**
	 * Setter for property 'restTemplate'.
	 *
	 * @param restTemplate Value to set for property 'restTemplate'.
	 */
	public void setRestTemplate(RestTemplate restTemplate) {
		this.restTemplate = restTemplate;
	}




}
